//
//  MXSlideShowView.m
//  MXSlideShow
//
//  Created by Bruce on 2019/10/9.
//  Copyright © 2019 陈学明. All rights reserved.
//

#import "MXSlideShowView.h"
#import "MXPageControl.h"
#import "UIButton+WebCache.h"

@interface MXSlideShowView ()
@property (nonatomic, strong) UIScrollView *slideShow;
@property (nonatomic, strong) UIButton *leftButton;
@property (nonatomic, strong) UIButton *middleButton;
@property (nonatomic, strong) UIButton *rightButton;
/// 总页数
@property (nonatomic, assign) NSInteger totalPage;
/// 定时器是否有效
@property (nonatomic, assign) BOOL isSourceActive;
/// 定时器
@property (nonatomic, strong) dispatch_source_t timer;
/// 已经开始自动滚动
@property (nonatomic, assign) BOOL autoScrolled;
/// 是否在手动滚动
@property (nonatomic, assign) BOOL isHand;
@end

@implementation MXSlideShowView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        
        [self addSubview:self.slideShow];
        [self.slideShow addSubview:self.leftButton];
        [self.slideShow addSubview:self.middleButton];
        [self.slideShow addSubview:self.rightButton];
        [self addSubview:self.pageControl];
        CGFloat slideW = frame.size.width;
        CGFloat slideH = frame.size.height;
        _slideShow.frame = CGRectMake(0, 0, slideW, slideH);
        _slideShow.contentSize = CGSizeMake(slideW * 3, slideH);
        
        _leftButton.frame = CGRectMake(0, 0, slideW, slideH);
        _middleButton.frame = CGRectMake(slideW, 0, slideW, slideH);
        _rightButton.frame = CGRectMake(slideW * 2, 0, slideW, slideH);
        
        _duration = 3;
        _autoRollPool = YES;
        
    }
    return self;
}

/** 自动滚动 */
- (void)automaticRolling {
    // 判断是否开启自动滚动
    if (!self.autoRollPool || self.duration <= 1) {
        return;
    }
    // 取消上一次设置的定时器
    if (self.timer && self.autoScrolled) {
        dispatch_cancel(self.timer);
        self.timer = nil;
    }
    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
    dispatch_source_set_timer(self.timer, dispatch_walltime(DISPATCH_TIME_NOW, self.duration * NSEC_PER_SEC), self.duration * NSEC_PER_SEC, 0);
    typeof(self) __weak weakSelf = self;
    dispatch_source_set_event_handler(self.timer, ^{
        dispatch_async(dispatch_get_main_queue(), ^{
//            NSLog(@"GCD Method:>>>>");
            if (!weakSelf) {
                return;
            }
            if (!weakSelf.autoRollPool) {
                weakSelf.autoScrolled = NO;
                dispatch_cancel(weakSelf.timer);
                return;
            }
            if (weakSelf.isHand) {
                return;
            }
            [weakSelf autoMoveToMaxPage];
        });
    });
    dispatch_resume(self.timer);
    // 运行定时器
    self.autoScrolled = YES;
}

- (void)autoMoveToMaxPage {
    if (self.totalPage <= 1) {
        return;
    }
    CGFloat offsetX = self.frame.size.width * 2;
    [UIView animateWithDuration:0.5 animations:^{
        self.slideShow.contentOffset = CGPointMake(offsetX, 0);
    } completion:^(BOOL finished) {
        if (finished) {
            [self moveImageView:offsetX];
        }
    }];
}

- (void)setFrame:(CGRect)frame {
    [super setFrame:frame];
    CGFloat slideW = self.frame.size.width;
    CGFloat slideH = self.frame.size.height;
    self.slideShow.frame = CGRectMake(0, 0, slideW, slideH);
    self.slideShow.contentSize = CGSizeMake(slideW * 3, slideH);
    
    self.leftButton.frame = CGRectMake(0, 0, slideW, slideH);
    self.middleButton.frame = CGRectMake(slideW, 0, slideW, slideH);
    self.rightButton.frame = CGRectMake(slideW * 2, 0, slideW, slideH);
}

- (void)setCircularBead:(CGFloat)circularBead {
    _circularBead = circularBead;
    self.leftButton.clipsToBounds = YES;
    self.middleButton.clipsToBounds = YES;
    self.rightButton.clipsToBounds = YES;
    
    self.leftButton.layer.cornerRadius = circularBead;
    self.middleButton.layer.cornerRadius = circularBead;
    self.rightButton.layer.cornerRadius = circularBead;
}

- (void)setEdgeInsets:(UIEdgeInsets)edgeInsets {
    _edgeInsets = edgeInsets;
    
    CGFloat slideW = self.frame.size.width;
    CGFloat slideH = self.frame.size.height;
    CGFloat itemY = edgeInsets.top;
    CGFloat itemX = edgeInsets.left;
    CGFloat itemW = slideW - edgeInsets.left - edgeInsets.right;
    CGFloat itemH = slideH - edgeInsets.top - edgeInsets.bottom;

    self.leftButton.frame = CGRectMake(itemX, itemY, itemW, itemH);
    self.middleButton.frame = CGRectMake(itemX + slideW, itemY, itemW, itemH);
    self.rightButton.frame = CGRectMake(itemX + (slideW * 2), itemY, itemW, itemH);
}

#pragma mark -- Events
- (void)setDelegate:(id<MXSlideShowViewDelegate>)delegate {
    _delegate = delegate;
    [self reloadData];
    if (_delegate) {
        [self automaticRolling];
    }
}
/** 刷新数据  */
- (void)reloadData {
    if (!self.delegate) {
        [self reset];
    } else {
        self.totalPage = [self.delegate numberPageSlideShowView:self];
        self.slideShow.scrollEnabled = self.totalPage > 1;
        [self moveToIdex:self.currentIndex];
    }
}

- (void)setDuration:(NSTimeInterval)duration {
    if (_duration == duration) {
        return;
    }
    _duration = duration;
    [self automaticRolling];
}

- (void)setAutoRollPool:(BOOL)autoRollPool {
    if (_autoRollPool == autoRollPool) {
        return;
    }
    _autoRollPool = autoRollPool;
    [self automaticRolling];
}

- (void)setCurrentIndex:(NSInteger)currentIndex {
    _currentIndex = currentIndex;
    self.pageControl.currentPage = currentIndex;
}

- (void)setTotalPage:(NSInteger)totalPage {
    _totalPage = totalPage;
    self.pageControl.numberOfPages = totalPage;
}

- (void)suspend {
    if (!self.autoRollPool) {
        return;
    }
    if (self.autoScrolled && _timer) {
        dispatch_cancel(_timer);
    }
}

- (void)activate {
    if (!self.autoRollPool) {
        return;
    }
    [self automaticRolling];
}

/** 重置列表  */
- (void)reset {
    self.totalPage = 0;
    self.currentIndex = 0;
    self.leftButton.tag = 0;
    self.middleButton.tag = 0;
    self.rightButton.tag = 0;
    [self.leftButton setBackgroundImage:self.placeImage forState:UIControlStateNormal];
    [self.middleButton setBackgroundImage:self.placeImage forState:UIControlStateNormal];
    [self.rightButton setBackgroundImage:self.placeImage forState:UIControlStateNormal];
    
    self.leftButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
    self.middleButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
    self.rightButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
}

- (void)clicked:(UIButton *)btn {
    if ([self.delegate respondsToSelector:@selector(slideShowView:didSelectedAtIndex:)]) {
        [self.delegate slideShowView:self didSelectedAtIndex:btn.tag];
    }
}

- (void)moveToIdex:(NSInteger)index {
    if (self.totalPage <= 0) {
        return;
    }
    if (index >= self.totalPage) {
        return;
    }
    self.currentIndex = index;
    NSInteger totalPage = self.totalPage - 1;
    
    NSInteger leftIndex = 0;
    NSInteger currentIndex = 0;
    NSInteger rightIndex = 0;
    if (index == 0) {
        leftIndex = totalPage;
        currentIndex = 0;
        rightIndex = 0;
        if (index < totalPage) {
            rightIndex = index + 1;
        }
    } else if (index == totalPage) {
        leftIndex = 0;
        if (totalPage > 0) {
            leftIndex = index - 1;
        }
        currentIndex = totalPage;
        rightIndex = 0;
    } else {
        leftIndex = index - 1;
        currentIndex = index;
        rightIndex = index + 1;
    }
    
    self.leftButton.tag = leftIndex;
    self.middleButton.tag = currentIndex;
    self.rightButton.tag = rightIndex;
    if ([self.delegate respondsToSelector:@selector(slideShowView:imageURLAtIndex:)]){
        NSURL *leftUrl = [self.delegate slideShowView:self imageURLAtIndex:leftIndex];
        NSURL *middleUrl = [self.delegate slideShowView:self imageURLAtIndex:currentIndex];
        NSURL *rightUrl = [self.delegate slideShowView:self imageURLAtIndex:rightIndex];
        [self.leftButton sd_setImageWithURL:leftUrl
                                    forState:UIControlStateNormal
                            placeholderImage:self.placeImage];
        [self.middleButton sd_setImageWithURL:middleUrl
                                     forState:UIControlStateNormal
                             placeholderImage:self.placeImage];
        [self.rightButton sd_setImageWithURL:rightUrl
                                    forState:UIControlStateNormal
                            placeholderImage:self.placeImage];
    } else {
        UIImage *leftImage = [self.delegate slideShowView:self imageAtIndex:leftIndex];
        UIImage *currentImage = [self.delegate slideShowView:self imageAtIndex:currentIndex];
        UIImage *rightImage = [self.delegate slideShowView:self imageAtIndex:rightIndex];
        [self.leftButton setBackgroundImage:leftImage forState:UIControlStateNormal];
        [self.middleButton setBackgroundImage:currentImage forState:UIControlStateNormal];
        [self.rightButton setBackgroundImage:rightImage forState:UIControlStateNormal];
    }
    [self.slideShow setContentOffset:CGPointMake(self.slideShow.frame.size.width, 0) animated:NO];
}

- (void)moveImageView:(CGFloat)offsetX {
    
    // 没有滑动
    if (offsetX ==  self.slideShow.frame.size.width) {
        return;
    }
    // 当前位置
    NSInteger temp = offsetX / self.slideShow.frame.size.width;
    NSInteger index = [self getCurrentImageIndex:temp];
    [self moveToIdex:index];
}

/** 获取当前图片索引 */
- (NSInteger)getCurrentImageIndex:(NSInteger)currentpage {
    NSInteger index = self.currentIndex;
    // 向右滑
    if (currentpage == 0) {
        if (index == 0) {
            index = self.totalPage - 1;
        } else {
            index -= 1;
        }
        // 向左滑
    } else if (currentpage == 2) {
        if (index == self.totalPage - 1) {
            index = 0;
        } else {
            index += 1;
        }
    }
    return index;
}

#pragma mark -- UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if ([self.delegate respondsToSelector:@selector(slideShowViewDidScroll:offsetX:)]) {
        CGFloat offsetX = (scrollView.contentOffset.x - scrollView.frame.size.width)  + scrollView.frame.size.width * self.currentIndex;
        [self.delegate slideShowViewDidScroll:self offsetX:offsetX];
    }
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    [self suspend];
    self.isHand = YES;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    [self moveImageView:scrollView.contentOffset.x];
    if (self.isHand) {
        [self automaticRolling];
        self.isHand = NO;
    }
}

#pragma mark -- lazy
- (UIScrollView *)slideShow {
    if (!_slideShow) {
        _slideShow = [[UIScrollView alloc] initWithFrame:self.bounds];
        _slideShow.delegate = self;
        _slideShow.pagingEnabled = YES;
        _slideShow.contentSize = CGSizeMake(self.frame.size.width * 3, self.frame.size.height);
        _slideShow.showsHorizontalScrollIndicator = NO;
        _slideShow.showsVerticalScrollIndicator = NO;
    }
    return _slideShow;
}

- (UIButton *)leftButton {
    if (!_leftButton) {
        _leftButton = [[UIButton alloc] initWithFrame:self.bounds];
        _leftButton.adjustsImageWhenHighlighted = NO;
        [_leftButton addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _leftButton;
}

- (UIButton *)middleButton {
    if (!_middleButton) {
        _middleButton = [[UIButton alloc] initWithFrame:self.bounds];
        _middleButton.adjustsImageWhenHighlighted = NO;
        [_middleButton addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _middleButton;
}

- (UIButton *)rightButton {
    if (!_rightButton) {
        _rightButton = [[UIButton alloc] initWithFrame:self.bounds];
        _rightButton.adjustsImageWhenHighlighted = NO;
        [_rightButton addTarget:self action:@selector(clicked:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _rightButton;
}
- (MXPageControl *)pageControl {
    if (!_pageControl) {
        CGFloat X = 0;
        CGFloat Y = self.frame.size.height - 30;
        CGFloat W = self.frame.size.width;
        CGFloat H = 30;
        _pageControl = [[MXPageControl alloc] initWithFrame:CGRectMake(X, Y, W, H)];
        _pageControl.numberOfPages = 0;
        _pageControl.currentPage = 0;
        _pageControl.pageControlType = MXPageControlTypeLine;
        _pageControl.pageControlAlignment = MXPageControlAlignmentCenter;
        _pageControl.pageMargin = 10.0;
        _pageControl.pageSizeWidth = 15;
        _pageControl.pageIndicatorColor = [UIColor colorWithUInt:0xf1f1f1];
        _pageControl.currentPageIndicatorColor =[UIColor colorWithUInt:0xE02020];
        _pageControl.showPageNumber = NO;
        _pageControl.pageControlType = MXPageControlTypeCircle;
    }
    return _pageControl;
}
#pragma mark -- 视图销毁
- (void)dealloc {
    if (self.timer) {
        // 当 source Timer 没有调用 dispatch_resume 的时候是不能调用 dispatch_cancel 方法的，不然会崩溃。也是为了 source Timer 的内存能够正确释放
        if (self.autoScrolled) {
            dispatch_resume(self.timer);
        }
        dispatch_cancel(self.timer);
        self.timer = nil;
    }
}

- (void)destructionView
{
    if (self.timer) {
        // 当 source Timer 没有调用 dispatch_resume 的时候是不能调用 dispatch_cancel 方法的，不然会崩溃。也是为了 source Timer 的内存能够正确释放
//        if (self.autoScrolled) {
//            dispatch_resume(self.timer);
//        }
//        dispatch_cancel(self.timer);
        self.timer = nil;
    }
}

@end
